package com.github_dididipapa.mall.product.service.impl;


import cn.hutool.core.bean.BeanUtil;

import com.github_dididipapa.common.to.component.Attr;
import com.github_dididipapa.mall.product.dao.*;
import com.github_dididipapa.mall.product.dto.AttrDto;
import com.github_dididipapa.mall.product.entity.*;
import com.github_dididipapa.mall.product.service.*;

import com.github_dididipapa.mall.product.vo.AttrVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github_dididipapa.common.utils.PageUtils;
import com.github_dididipapa.common.utils.Query;

import org.springframework.transaction.annotation.Transactional;

@Slf4j
@RequiredArgsConstructor
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {


    private final AttrAttrgroupRelationService attrAttrgroupRelationService;
    private final CategoryDao categoryDao;
    private final CategoryService categoryService;
    private final AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    private final AttrGroupDao attrGroupDao;
    private final ProductAttrValueDao productAttrValueDao;
    private final AttrDao attrDao;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtil.copyProperties(attr, attrEntity);
        //保存基本数据
        this.save(attrEntity);
        //保存关联数据
        AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
        attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
        attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
        attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);
    }

    //分页
    /**
     * 属性类型[0-销售属性，1-基本属性，2-既是销售属性又是基本属性]
     */
    @Override
    public PageUtils getBaseAttrPage(Map<String, Object> params, Long catelogId) {
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params));
        PageUtils pageUtils = new PageUtils(page);

        //查询Attr转为AttrVo
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("attr_type", 1).or().eq("attr_type", 2);
        if(catelogId != 0) {
            wrapper.eq("catelog_id",catelogId);
        }

        List<AttrEntity> attrEntities = attrDao.selectList(wrapper);
        List<AttrVo> attrVos = attrEntities.stream().map(item -> {
            AttrVo attrVo = new AttrVo();
            BeanUtil.copyProperties(item, attrVo);
            return attrVo;
        }).collect(Collectors.toList());

        //查询catelogName并赋值
        List<CategoryEntity> categoryEntities = categoryDao.selectList(new QueryWrapper<CategoryEntity>());
        attrVos.stream().forEach(item -> {
            categoryEntities.stream().forEach(category -> {
                if(category.getCatId().equals(item.getCatelogId())) {
                    item.setCatelogName(category.getName());
                }
            });
        });

        //查询groupName并赋值
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new QueryWrapper<>());
        attrVos.stream().forEach(item -> {
            attrGroupEntities.stream().forEach(group -> {
                if(group.getCatelogId().equals(item.getCatelogId())) {
                    item.setAttrGroupId(group.getAttrGroupId());
                    item.setGroupName(group.getAttrGroupName());
                }
            });
        });

        pageUtils.setList(attrVos);
        return pageUtils;
    }


    /**
     * 属性类型[0-销售属性，1-基本属性，2-既是销售属性又是基本属性]
     */
    @Override
    public PageUtils getByCategoryId(Map<String, Object> params, Long catelogId) {
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params));
        PageUtils pageUtils = new PageUtils(page);

        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("attr_type", 0).or().eq("attr_type", 2);
        if(catelogId != 0) wrapper.eq("catelog_id",catelogId);

        List<AttrEntity> attrEntities = attrDao.selectList(wrapper);
        List<AttrDto> attrDtos = attrEntities.stream().map(AttrDto::new).collect(Collectors.toList());
        if(attrDtos.isEmpty()) {
            pageUtils.setList(attrDtos);
            return pageUtils;
        }

        //查询groupName
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new QueryWrapper<>());
        attrDtos.stream().forEach(item -> {
            attrGroupEntities.stream().forEach(group -> {
                if(group.getCatelogId().equals(item.getCatelogId())) {
                    item.setAttrGroupId(group.getAttrGroupId());
                    item.setGroupName(group.getAttrGroupName());
                }
            });
        });
        pageUtils.setList(attrDtos);
        return pageUtils;
    }

    @Override
    public List<ProductAttrValueEntity> getBaseAttrListForSpu(Long spuId) {

        return productAttrValueDao.selectList(
                new QueryWrapper<ProductAttrValueEntity>()
                        .eq("spu_id", spuId));
    }

    @Override
    public AttrVo getAttrInfo(Long attrId) {
        AttrEntity attrEntity = this.getById(attrId);
        AttrVo attrVo = new AttrVo();
        BeanUtil.copyProperties(attrEntity,attrVo);
        //查询attrGroupId
        long  attrGroupId = attrAttrgroupRelationService.getAttrGroupIdByAttrId(attrId);
        attrVo.setAttrGroupId(attrGroupId);
        //查询catelogPath
        if(attrEntity != null) attrVo.setCatelogPath(categoryService.getCatelogPath(attrEntity.getCatelogId()));
        return attrVo;
    }

    /**
     * @description:
     * @author: dididi_papa
     * @date: 2025/6/14 下午11:18
     * @param: attr
     * @return: void
     **/
    @Transactional
    @Override
    public void updateByAttrVo(AttrVo attr) {
        //更新AttrEntity
        AttrEntity attrEntity = new AttrEntity();
        BeanUtil.copyProperties(attr,attrEntity);
        this.updateById(attrEntity);

        //更新attr_group
        attrAttrgroupRelationDao.updateDetail(attr.getAttrId(), attr.getAttrGroupId());

        //更新catelogId
        attrGroupDao.updateCategory(attr.getAttrGroupId(), attr.getCatelogId());
    }

    /**
     * 获取未关联属性列表（分页）
     * 
     * @param attrGroupId 属性分组ID，用于查询对应的分类及其他相关分组
     * @param params      分页参数，包含当前页码、每页大小等信息
     * 
     * @return PageUtils 返回分页结果，包含未被其他分组使用的属性列表
     */
    @Transactional(readOnly = true)
    @Override
    public PageUtils getNoAttrByAttrGroupId(Long attrGroupId, Map<String, Object> params) {
        /*
         * 步骤一：获取当前属性分组
         * 若找不到对应属性分组则抛出异常
         */
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        if (attrGroupEntity == null) {
            log.info("attrGroupId: {}对应的属性分组不存在",attrGroupId);
            throw new IllegalArgumentException("属性分组不存在");
        }
        Long catelogId = attrGroupEntity.getCatelogId();

        /*
         * 步骤二：查找当前属性分组下的所有规格参数
         *
         */
        List<AttrEntity> attrEntities = attrDao.selectList(
                new QueryWrapper<AttrEntity>().eq("catelog_id",catelogId)
        );

        /*
         * 步骤三：从属性分组中获取已关联的属性id
         */
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId)
        );

        List<Long> usedAttrIds = relationEntities.stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());

        /*
         * 步骤四：从当前属性分组下的所有规格参数下排除已经关联的属性
         */
        List<AttrEntity> data = attrEntities.stream()
                .filter(attrEntity -> !usedAttrIds.contains(attrEntity.getAttrId()))
                .collect(Collectors.toList());


        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params));
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(data);

        return pageUtils;
    }

    /**
     * @description:
     * @author: dididi_papa
     * @date: 2025/7/3 下午10:09
     * @param: [attrIds]
     * @return: java.util.List<java.lang.Long>
     **/
    @Override
    public List<Long> getBaseAttrs(List<Long> attrIds) {

        return attrDao.selectSearchAttrIds(attrIds);
    }


}